using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using Path = System.IO.Path;

namespace InnerFireEditor {
  public class FileTabManager {
    private readonly TabControl _tabControl;
    private readonly List<FileTabManagerItem> _tabItems = new List<FileTabManagerItem>();

    public FileTabManager(TabControl tabControl) {
      _tabControl = tabControl ?? throw new ArgumentNullException(nameof(tabControl));
    }

    public void Open(string path) {
      if (!File.Exists(path))
        throw new FileNotFoundException("文件不存在", path);

      // 检查是否已经打开
      var existingTab = _tabItems.FirstOrDefault(x => x.FilePath == path);
      if (existingTab != null) {
        _tabControl.SelectedItem = existingTab.TabItem;
        return;
      }

      var textBox = CreateEditor();
      textBox.Text = File.ReadAllText(path);

      var tabItem = CreateTabItem(Path.GetFileName(path), textBox, path);

      _tabControl.Items.Add(tabItem);
      _tabControl.SelectedItem = tabItem;

      _tabItems.Add(new FileTabManagerItem(path, textBox, tabItem));
    }

    public FileTabManagerItem GetCurrentItem() {
      var currentTabItem = _tabControl.SelectedItem as TabItem;
      if (currentTabItem == null) return null;
      return _tabItems.FirstOrDefault(x => x.TabItem == currentTabItem);
    }

    public string GetCurrentFile() {
      return GetCurrentItem()?.FilePath;
    }

    public string GetCurrentText() {
      return GetCurrentItem()?.Editor.Text;
    }

    public bool Save(string path = null) {
      var currentTabItem = _tabControl.SelectedItem as TabItem;
      if (currentTabItem == null) return false;

      var tabManagerItem = _tabItems.FirstOrDefault(x => x.TabItem == currentTabItem);
      if (tabManagerItem == null) return false;

      try {
        string savePath = path ?? tabManagerItem.FilePath;
        if (string.IsNullOrEmpty(savePath))
          return false;

        File.WriteAllText(savePath, tabManagerItem.Editor.Text);
        tabManagerItem.FilePath = savePath;
        UpdateTabTitle(tabManagerItem, Path.GetFileName(savePath), true);
        return true;
      } catch (Exception ex) {
        MessageBox.Show($"保存文件时出错: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
        return false;
      }
    }

    private TextBox CreateEditor() {
      return new TextBox {
        AcceptsReturn = true,
        AcceptsTab = true,
        VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
        HorizontalScrollBarVisibility = ScrollBarVisibility.Auto,
        FontFamily = new System.Windows.Media.FontFamily("Consolas"),
        FontSize = 14
      };
    }

    private TabItem CreateTabItem(string title, TextBox editor, string filePath) {
      var tabItem = new TabItem {
        Header = CreateTabHeader(title),
        Content = editor,
        Tag = filePath
      };

      editor.TextChanged += (s, e) =>
          MarkTextChanged(tabItem);

      return tabItem;
    }

    private object CreateTabHeader(string title) {
      var headerStack = new StackPanel { Orientation = Orientation.Horizontal };
      headerStack.Children.Add(new TextBlock { Text = title });

      var closeButton = new Button {
        Content = "×",
        Width = 20,
        Height = 20,
        Margin = new Thickness(5, 0, 0, 0),
        Padding = new Thickness(0),
        Focusable = false
      };
      closeButton.Click += CloseTab_Click;
      headerStack.Children.Add(closeButton);

      return headerStack;
    }

    private void CloseTab_Click(object sender, RoutedEventArgs e) {
      if (sender is Button button && button.Parent is StackPanel headerStack &&
          headerStack.Parent is TabItem tabItem) {
        // 检查是否有未保存的更改
        var tabManagerItem = _tabItems.FirstOrDefault(x => x.TabItem == tabItem);
        if (tabManagerItem != null) {
          string originalContent = File.Exists(tabManagerItem.FilePath) ?
              File.ReadAllText(tabManagerItem.FilePath) : string.Empty;

          if (tabManagerItem.Editor.Text != originalContent) {
            var result = MessageBox.Show("文件已修改，是否保存更改？", "保存更改",
                MessageBoxButton.YesNoCancel, MessageBoxImage.Question);

            if (result == MessageBoxResult.Yes && !Save(tabManagerItem.FilePath))
              return; // 用户取消保存或保存失败
            else if (result == MessageBoxResult.Cancel)
              return; // 用户取消关闭
          }

          _tabControl.Items.Remove(tabItem);
          _tabItems.Remove(tabManagerItem);
        }
      }
    }

    private void MarkTextChanged(TabItem tabItem) {
      var tabManagerItem = _tabItems.FirstOrDefault(x => x.TabItem == tabItem);
      if (tabManagerItem == null) return;

      var headerStack = tabManagerItem.TabItem.Header as StackPanel;
      if (headerStack != null && headerStack.Children.Count > 0) {
        var textBlock = headerStack.Children[0] as TextBlock;
        if (textBlock != null && !textBlock.Text.EndsWith("*")) {
          textBlock.Text += "*";
        }
      }
    }


    /// <summary>
    /// 保存所有打开的文件
    /// </summary>
    /// <param name="is_close">保存后是否关闭所有标签页</param>
    /// <returns>是否全部保存成功</returns>
    public bool SaveAll(bool is_close = false) {
      bool allSaved = true;
      var tabsToClose = new List<FileTabManagerItem>();

      // 遍历所有标签页（创建副本避免修改集合）
      foreach (var tabItem in _tabItems.ToList()) {
        // 只保存有文件路径的标签页（跳过未保存的新文件）
        if (!string.IsNullOrEmpty(tabItem.FilePath)) {
          _tabControl.SelectedItem = tabItem.TabItem;

          if (!Save(tabItem.FilePath)) {
            allSaved = false;
            continue; // 跳过保存失败的标签页
          }

          if (is_close) {
            tabsToClose.Add(tabItem);
          }
        }
        // 无文件路径的新文件直接跳过（不保存也不关闭）
      }

      // 关闭需要处理的标签页
      if (is_close) {
        foreach (var tabItem in tabsToClose) {
          CloseTab(tabItem);
        }
      }

      return allSaved;
    }

    /// <summary>
    /// 关闭所有标签页
    /// </summary>
    private void CloseAllTabs() {
      foreach (var tabItem in _tabItems.ToList()) {
        CloseTab(tabItem);
      }
    }

    /// <summary>
    /// 安全关闭单个标签页
    /// </summary>
    private void CloseTab(FileTabManagerItem tabItem) {
      _tabControl.Items.Remove(tabItem.TabItem);
      _tabItems.Remove(tabItem);
    }

    /// <summary>
    /// 获取标签页标题（去掉*标记）
    /// </summary>
    private string GetTabTitle(FileTabManagerItem item) {
      if (item.TabItem.Header is StackPanel headerStack &&
          headerStack.Children.Count > 0 &&
          headerStack.Children[0] is TextBlock textBlock) {
        return textBlock.Text.Replace("*", "");
      }
      return item.TabItem.Header.ToString();
    }

    /// <summary>
    /// 搜索并重命名文件或目录路径
    /// </summary>
    /// <param name="oldPath">原始路径（文件或目录）</param>
    /// <param name="newPath">新路径</param>
    /// <returns>成功更新的项目数量</returns>
    public int SearchAndRename(string oldPath, string newPath, bool is_file) {
      if (string.IsNullOrEmpty(oldPath) || string.IsNullOrEmpty(newPath))
        return 0;

      int updatedCount = 0;
      oldPath = Path.GetFullPath(oldPath).TrimEnd('\\');
      newPath = Path.GetFullPath(newPath).TrimEnd('\\');

      try {
        if (is_file) {
          // 文件重命名逻辑
          var item = _tabItems.FirstOrDefault(x =>
              string.Equals(x.FilePath, oldPath, StringComparison.OrdinalIgnoreCase));

          if (item != null) {
            item.FilePath = newPath;
            UpdateTabTitle(item, Path.GetFileName(newPath));
            updatedCount++;
          }
        } else {
          // 目录重命名逻辑
          foreach (var item in _tabItems.Where(x =>
              !string.IsNullOrEmpty(x.FilePath))) {
            string fullPath = Path.GetFullPath(item.FilePath);
            if (fullPath.StartsWith(oldPath, StringComparison.OrdinalIgnoreCase)) {
              string relativePath = fullPath.Substring(oldPath.Length).TrimStart('\\');
              item.FilePath = Path.Combine(newPath, relativePath);
              UpdateTabTitle(item, Path.GetFileName(item.FilePath));
              updatedCount++;
            }
          }
        }
      } catch (Exception ex) {
        MessageBox.Show($"路径更新失败: {ex.Message}", "错误",
            MessageBoxButton.OK, MessageBoxImage.Error);
      }

      return updatedCount;
    }

    // 辅助方法：更新标签页标题
    private void UpdateTabTitle(FileTabManagerItem item, string newTitle, bool clear_modify = false) {
      if (item.TabItem.Header is StackPanel headerStack &&
          headerStack.Children.Count > 0 &&
          headerStack.Children[0] is TextBlock textBlock) {
        // 保留修改标记（*）
        bool hasModification = textBlock.Text.EndsWith("*");
        if (clear_modify) {
          hasModification = false;
        }

        textBlock.Text = hasModification ? $"{newTitle}*" : newTitle;
      } else {
        item.TabItem.Header = newTitle;
      }
    }

    /// <summary>
    /// 根据路径关闭关联的标签页
    /// </summary>
    /// <param name="path">文件或目录路径</param>
    /// <param name="isDir">是否为目录路径</param>
    /// <returns>关闭的标签页数量</returns>
    public int CloseTabByPath(string path, bool isDir = false) {
      if (string.IsNullOrWhiteSpace(path))
        return 0;

      path = Path.GetFullPath(path); // 标准化路径

      var tabsToClose = _tabItems
          .Where(item => !string.IsNullOrEmpty(item.FilePath))
          .Where(item => isDir
              ? Path.GetFullPath(item.FilePath).StartsWith(path, StringComparison.OrdinalIgnoreCase)
              : string.Equals(Path.GetFullPath(item.FilePath), path, StringComparison.OrdinalIgnoreCase))
          .ToList();

      foreach (var tabItem in tabsToClose) {
        _tabControl.Items.Remove(tabItem.TabItem);
        _tabItems.Remove(tabItem);
      }

      return tabsToClose.Count;
    }

    public void ReloadFile(string filePath) {
      int updatedCount = 0;
      filePath = Path.GetFullPath(filePath).TrimEnd('\\');

      try {
        // 文件重命名逻辑
        var item = _tabItems.FirstOrDefault(x =>
            string.Equals(x.FilePath, filePath, StringComparison.OrdinalIgnoreCase));
        if (item != null) {
          item.Editor.Text = File.ReadAllText(filePath);
        }
      } catch (Exception ex) {
        MessageBox.Show($"路径更新失败: {ex.Message}", "错误",
            MessageBoxButton.OK, MessageBoxImage.Error);
      }

    }

  }
}